/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 *
 */
import { FileSet } from '@ohos/hvigor';
import path from 'path';

import { CommonConst } from '../const/common-const.js';

import { TaskNames } from './common/task-names.js';
import { GlobalProjectDataService } from './service/global-project-data-service.js';
import { TargetTaskService } from './service/target-task-service.js';
import { isSigned } from './sign/sign-util.js';
import { SignRemoteHsp } from './sign-remote-hsp.js';
import { DependencyManager } from "../project/dependency/dependency-manager";

export class SignProjectRemoteHsp extends SignRemoteHsp {
  constructor(targetService: TargetTaskService) {
    super(targetService, TaskNames.CommonTask.SIGN_PROJECT_REMOTE_HSP);
    const projectOhpmPath = this.service.getProjectModel().getRemoteHspPath();
    const dependencyManager = new DependencyManager(this.projectModel.isFaMode(), this.moduleModel, this.projectModel);
    const { npmDependencies } = dependencyManager.collectAllDependencies();
    this.getProjectSignRemoteHspMap(projectOhpmPath, npmDependencies);
    if (this.allProjectRequiredSignRemoteHspMap.size > 0) {
      this.createProjectRemoteHspCache();
      this.initAllSignRemoteHspList(
        this.allProjectHspPathList,
        this.allProjectRemoteHspPathList,
        this.allProjectSignedRemoteHspList,
        this.allProjectRequiredSignRemoteHspMap,
      );
    }
  }

  taskShouldDo(): boolean {
    return isSigned(this.projectModel);
  }

  /**
   * 由于多模块都需要依赖工程级remote_hsp签名方法，所以使用promise让所以模块级的remote_hsp等待该任务执行结束
   * 如果promise = projectUnsigned说明不存在工程级remote_hsp签名任务，新建一个promise对象使所有模块级签名任务等待其执行
   * @protected
   */
  protected async doTaskAction() {
    // 初始化projectRemoteHspPromise为undefined,第一次添加依赖时将projectRemoteHspPromise赋值projectSignPrepare,避免后续依赖被添加
    const promise = GlobalProjectDataService.getInstance().getProjectRemoteHspPromise();
    if (promise && this.allProjectSignedRemoteHspList.length === 0) {
      this._log.debug('the project remote_hsps are signing or signed, just await');
      await promise;
      return;
    }

    const signPromise = this.doSignAction();

    GlobalProjectDataService.getInstance().setProjectRemoteHspPromise(signPromise);

    await signPromise;
  }

  private async doSignAction() {
    try {
      if (this.allProjectSignedRemoteHspList.length === 0) {
        return;
      }
      const projectHspDir = this.projectModel.getCacheRemoteHspPath(this.targetData.getProduct().name);
      const projectRemoteHspCachePath = path.resolve(projectHspDir, CommonConst.REMOTE_HSP_CACHE);
      this._log.debug(`this.allProjectSignedRemoteHspList ${this.allProjectSignedRemoteHspList}`);
      for (const signOhpmModel of this.allProjectSignedRemoteHspList) {
        await this.submitSignWorker(signOhpmModel, () => {
          this.signRemoteHspCallBack(projectRemoteHspCachePath, signOhpmModel.getOutPutFilePath());
        });
      }
    } catch (err: any) {
      this._log._buildError(err)._printErrorAndExit();
    }
  }

  declareInputFiles(): FileSet {
    return super.declareInputFiles().addEntries([...this.allProjectRemoteHspPathList], {
      isDirectory: false,
    });
  }

  declareOutputFiles(): FileSet {
    return super.declareOutputFiles().addEntries([...this.allProjectHspPathList], { isDirectory: false });
  }

  initTaskDepends(): void {
    // no task
  }
}
